import React, { useCallback, useRef, useState, useEffect } from 'react';
import TracklineVisual from './TracklineVisual';

function VisualTrackline() {
  const [lines, setLines] = useState([]);
  const [platforms, setPlatforms] = useState([]);
  const [tracklights, setTracklights] = useState([]); // 信号机数据

  const [trains, setTrains] = useState([]);
  const [signals, setSignals] = useState([]); // 信号机数据

  const [fileName, setFileName] = useState('config.json'); // 输入框控制
  const [listenURL, setlistenURL] = useState('http://localhost:3003/train'); // 监听地址
  const [mode, setMode] = useState("none"); // "edit" | "drawPlatform" | "delete" | "editTracklight" | "none"

  const [rows, setRows] = useState(30);
const [columns, setColumns] = useState(50);

  const editMode = mode === "edit";
  const deleteMode = mode === "delete";
  const drawPlatformMode = mode === "drawPlatform";
  const editTracklightMode = mode === "editTracklight";

  const svgRef = useRef();

  const intervalRef = useRef(null);

  const getOffsetFromUser = () => {
    return new Promise((resolve) => {
      const container = document.createElement('div');
      container.style.position = 'fixed';
      container.style.top = '50%';
      container.style.left = '50%';
      container.style.transform = 'translate(-50%, -50%)';
      container.style.background = '#fff';
      container.style.padding = '20px';
      container.style.border = '1px solid #ccc';
      container.style.boxShadow = '0 0 10px rgba(0,0,0,0.3)';
      container.style.zIndex = 10000;
      container.style.fontSize = '14px';
      container.style.fontFamily = 'sans-serif';
  
      container.innerHTML = `
        <div style="margin-bottom: 10px;">
          <label>横向偏移（列）:
            <input id="colOffsetInput" type="number" min="0" step="1" value="0"
              oninput="this.value = this.value.replace(/[^\\d]/g, '')"
            />
          </label>
        </div>
        <div style="margin-bottom: 10px;">
          <label>纵向偏移（行）:
            <input id="rowOffsetInput" type="number" min="0" step="1" value="0"
              oninput="this.value = this.value.replace(/[^\\d]/g, '')"
            />
          </label>
        </div>
        <div style="margin-bottom: 12px;">
          <label><input type="checkbox" id="clearBeforeLoad" /> 同时清空当前画板</label>
        </div>
        <button id="confirmBtn">确定</button>
        <button id="cancelBtn" style="margin-left:10px;">取消</button>
      `;
  
      document.body.appendChild(container);
  
      container.querySelector('#confirmBtn').onclick = () => {
        const rowOffset = Math.floor(Number(container.querySelector('#rowOffsetInput').value)) || 0;
        const colOffset = Math.floor(Number(container.querySelector('#colOffsetInput').value)) || 0;
        const clearBeforeLoad = container.querySelector('#clearBeforeLoad').checked;
  
        document.body.removeChild(container);
        resolve([rowOffset, colOffset, clearBeforeLoad]);
      };
  
      container.querySelector('#cancelBtn').onclick = () => {
        document.body.removeChild(container);
        resolve(null); // 用户取消
      };
    });
  };

  const getExportConfigFromUser = () => {
    return new Promise((resolve) => {
      const container = document.createElement('div');
      container.style.position = 'fixed';
      container.style.top = '50%';
      container.style.left = '50%';
      container.style.transform = 'translate(-50%, -50%)';
      container.style.background = '#fff';
      container.style.padding = '20px';
      container.style.border = '1px solid #ccc';
      container.style.boxShadow = '0 0 10px rgba(0,0,0,0.3)';
      container.style.zIndex = 10000;
      container.style.fontSize = '14px';
      container.style.fontFamily = 'sans-serif';
  
      container.innerHTML = `
        <div style="margin-bottom: 10px;">
          <label><input type="radio" name="exportMode" value="all" checked /> 全部导出</label>
        </div>
        <div style="margin-bottom: 10px;">
          <label><input type="radio" name="exportMode" value="range" /> 选择范围导出</label>
        </div>
        <div id="rangeInputs" style="margin-bottom: 10px; opacity: 0.5; pointer-events: none;">
          <div style="margin-bottom: 6px;">
            左上角横列坐标: <input id="leftInput" type="number" value="0" min="0" step="1" />
            左上角纵行坐标: <input id="topInput" type="number" value="0" min="0" step="1" />
          </div>
          <div>
            右下角横列坐标: <input id="rightInput" type="number" value="10" min="0" step="1" />
            右下角纵行坐标: <input id="bottomInput" type="number" value="10" min="0" step="1" />
          </div>
        </div>
        <button id="confirmExport">导出</button>
        <button id="cancelExport" style="margin-left: 10px;">取消</button>
      `;
  
      document.body.appendChild(container);
  
      const radios = container.querySelectorAll('input[name="exportMode"]');
      const rangeSection = container.querySelector('#rangeInputs');
  
      radios.forEach((radio) => {
        radio.onchange = () => {
          if (radio.value === 'range') {
            rangeSection.style.opacity = '1';
            rangeSection.style.pointerEvents = 'auto';
          } else {
            rangeSection.style.opacity = '0.5';
            rangeSection.style.pointerEvents = 'none';
          }
        };
      });
  
      container.querySelector('#confirmExport').onclick = () => {
        const mode = container.querySelector('input[name="exportMode"]:checked').value;
        if (mode === 'range') {
          const col1 = Math.floor(Number(container.querySelector('#leftInput').value));
          const row1 = Math.floor(Number(container.querySelector('#topInput').value));
          const col2 = Math.floor(Number(container.querySelector('#rightInput').value));
          const row2 = Math.floor(Number(container.querySelector('#bottomInput').value));
          document.body.removeChild(container);
          resolve({ mode: 'range', col1, row1, col2, row2 });
        } else {
          document.body.removeChild(container);
          resolve({ mode: 'all' });
        }
      };
  
      container.querySelector('#cancelExport').onclick = () => {
        document.body.removeChild(container);
        resolve(null); // 用户取消
      };
    });
  };

const startListening = () => {
  if (!listenURL) return alert("请输入监听地址");

  stopListening(); // 先清除旧的监听（如果有）

  intervalRef.current = setInterval(async () => {
    try {
      const res = await fetch(listenURL);
      const data = await res.json();
      if (Array.isArray(data.trains)) {
        setTrains(data.trains || []);
        setSignals(data.signals || []);
      }
    } catch (err) {
      console.error("获取列车数据失败:", err);
    }
  }, 200); // 每 200ms 获取一次数据
};

const stopListening = () => {
  if (intervalRef.current) {
    clearInterval(intervalRef.current);
    intervalRef.current = null;
  }
};

const checkAndExpandCanvas = () => {
  let maxRow = 0, maxCol = 0;

  lines.forEach(({ start, end }) => {
    maxRow = Math.max(maxRow, start.row, end.row);
    maxCol = Math.max(maxCol, start.col, end.col);
  });

  platforms.forEach(({ row, col }) => {
    maxRow = Math.max(maxRow, row);
    maxCol = Math.max(maxCol, col);
  });

  tracklights.forEach(({ row, col }) => {
    maxRow = Math.max(maxRow, row);
    maxCol = Math.max(maxCol, col);
  });

  trains.forEach((train) => {
    train.trackNo?.forEach((no) => {
      const match = lines.find((l) => l.no === no);
      if (match) {
        maxRow = Math.max(maxRow, match.start.row, match.end.row);
        maxCol = Math.max(maxCol, match.start.col, match.end.col);
      }
    });
  });

  // 仅当接近边界时才扩展
  if (maxRow >= rows - 2) setRows((prev) => prev + 20);
  if (maxCol >= columns - 2) setColumns((prev) => prev + 20);
};

useEffect(() => {
  checkAndExpandCanvas();
}, [lines, platforms, tracklights, trains]);

  const handleLineDrawn = useCallback((newLine) => {
    setLines((prevLines) => [...prevLines, { ...newLine, no: "", occupied: false }]);
  });

  const updateLine = useCallback((index, updatedLine) => {
    setLines((prev) => {
      const newLines = [...prev];
      newLines[index] = updatedLine;
      return newLines;
    });
  });

  const updateTracklight = useCallback((index, updatedLight) => {
    setTracklights((prev) => {
      const next = [...prev];
      next[index] = updatedLight;
      return next;
    });
  });

  const deleteTracklight = useCallback((index) => {
    setTracklights((prev) => prev.filter((_, i) => i !== index));
  });

  const deletePlatform = useCallback((index) => {
    setPlatforms((prev) => prev.filter((_, i) => i !== index));
  });

  const deleteLine = useCallback((index) => {
    setLines((prev) => prev.filter((_, i) => i !== index));
  });

  const clearCanvas = useCallback(() => {
    const confirmed = window.confirm("确定要清空画板吗？该操作不可撤销。");
    if (confirmed) {
      setLines([]);
      setPlatforms([]);
      setTracklights([]);
      setTrains([]);
      stopListening(); // 停止监听
    }
  });

  const loadDataFromFile = async () => {
    try {
      const res = await fetch(`/${fileName}`);
      if (!res.ok) throw new Error('文件读取失败');
      const json = await res.json();
  
      const result = await getOffsetFromUser();
      if (!result) return; // 用户取消
  
      const [offsetRow, offsetCol, shouldClear] = result;
  
      const applyOffset = (obj) => ({
        ...obj,
        row: obj.row + offsetRow,
        col: obj.col + offsetCol,
      });
  
      const offsetLines = (json.lines || []).map((line) => ({
        ...line,
        start: applyOffset(line.start),
        end: applyOffset(line.end),
      }));
  
      const offsetPlatforms = (json.platforms || []).map(applyOffset);
      const offsetTracklights = (json.tracklights || []).map(applyOffset);
  
      if (shouldClear) {
        stopListening();
        setLines(offsetLines);
        setPlatforms(offsetPlatforms);
        setTracklights(offsetTracklights);
        setTrains([]);
      } else {
        setLines((prev) => [...prev, ...offsetLines]);
        setPlatforms((prev) => [...prev, ...offsetPlatforms]);
        setTracklights((prev) => [...prev, ...offsetTracklights]);
      }
    } catch (err) {
      alert(`读取失败：${err.message}`);
    }
  };

  const exportToJson = async () => {
    const config = await getExportConfigFromUser();
    if (!config) return;
  
    let exportedLines = [];
    let exportedPlatforms = [];
    let exportedTracklights = [];
  
    if (config.mode === 'all') {
      // 全部导出
      exportedLines = lines.map(({ occupied, ...rest }) => rest);
      exportedPlatforms = platforms;
      exportedTracklights = tracklights.map(({ state, ...rest }) => rest);
    } else if (config.mode === 'range') {
      const { col1, row1, col2, row2 } = config;
  
      const inRange = (row, col) =>
        row >= row1 && row <= row2 && col >= col1 && col <= col2;
  
      const applyRelative = (obj) => ({
        ...obj,
        row: obj.row - row1,
        col: obj.col - col1,
      });
  
      exportedLines = lines
        .filter((line) =>
          inRange(line.start.row, line.start.col) && inRange(line.end.row, line.end.col)
        )
        .map((line) => ({
          ...line,
          start: applyRelative(line.start),
          end: applyRelative(line.end),
        }));
  
      exportedPlatforms = platforms
        .filter((p) => inRange(p.row, p.col))
        .map(applyRelative);
  
      exportedTracklights = tracklights
        .filter((t) => inRange(t.row, t.col))
        .map(({ state, ...rest }) => applyRelative(rest));
    }
  
    const data = {
      lines: exportedLines,
      platforms: exportedPlatforms,
      tracklights: exportedTracklights,
    };
  
    const blob = new Blob([JSON.stringify(data, null, 2)], {
      type: 'application/json',
    });
  
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'track_data.json';
    a.click();
    URL.revokeObjectURL(url);
  };

  const exportSVG = () => {
    if (!svgRef.current) return;

    // 获取 SVG 字符串
    const svgContent = svgRef.current.outerHTML;
    const blob = new Blob([svgContent], { type: 'image/svg+xml;charset=utf-8' });
    const url = URL.createObjectURL(blob);

    // 创建并触发下载
    const a = document.createElement('a');
    a.href = url;
    a.download = 'trackline_visual.svg';
    a.click();

    // 预览窗口
    const preview = window.open();
    if (preview) {
      preview.document.write(`
        <html>
          <head><title>SVG 预览</title></head>
          <body style="margin:0; padding:0; display:flex; justify-content:center; align-items:center; height:100vh; background:#f9f9f9;">
            <img src="${url}" style="max-width:100%; max-height:100%;" />
          </body>
        </html>
      `);
      preview.document.close();
    }

    // 不立即 revoke URL，防止图像加载失败
    setTimeout(() => URL.revokeObjectURL(url), 10000);
  };

  return (
    <div>
      {/* 输入框 + 读取按钮 */}
      <input
        type="text"
        value={fileName}
        onChange={(e) => setFileName(e.target.value)}
        placeholder="请输入文件名"
        onKeyDown={(e) => {
          if (e.key === 'Enter') {
            loadDataFromFile(); // ⏎ 回车自动加载
          }
        }}
      />
      <button onClick={loadDataFromFile} style={{ marginLeft: '4px' }}>
        加载数据
      </button>
      <button onClick={exportToJson} style={{ marginLeft: '4px' }}>
        导出数据
      </button>

      <button onClick={exportSVG} style={{ marginLeft: '4px' }}>
        导出 SVG
      </button>

      {/* 启用轨道编辑 */}
      <button
        onClick={() => setMode(mode === "edit" ? "none" : "edit")}
        style={{ marginLeft: '16px', width: '100px' }}
      >
        {mode === "edit" ? '✅ 编辑中' : '🛠️ 编辑轨道'}
      </button>

      {/* 启用站台编辑 */}
      <button
        onClick={() => setMode(mode === "drawPlatform" ? "none" : "drawPlatform")}
        style={{ marginLeft: '4px', width: '100px' }}
      >
        {mode === "drawPlatform" ? '✅ 点击添加' : '➕ 新增站台'}
      </button>

      {/* 启用信号机编辑 */}
      <button
        onClick={() => setMode(mode === "editTracklight" ? "none" : "editTracklight")}
        style={{ marginLeft: '4px', width: '125px' }}
      >
        {mode === "editTracklight" ? '✅ 编辑信号机中' : '🛠️ 编辑信号机'}
      </button>

      {/* 启用组件删除 */}
      <button
        onClick={() => setMode(mode === "delete" ? "none" : "delete")}
        style={{ marginLeft: '16px', width: '100px' }}
      >
        {mode === "delete" ? '✅ 删除中' : '🗑️ 删除组件'}
      </button>

      {/* 清空画布 */}
      <button
        onClick={clearCanvas}
        style={{ marginLeft: '4px' }}
      >
        ⚠️ 清空画板
      </button>

      {/* 第二行：监听地址 + 控制按钮 */}
      <div style={{ marginTop: '8px', display: 'flex', alignItems: 'center' }}>
        <input
          type="text"
          value={listenURL}
          onChange={(e) => setlistenURL(e.target.value)}
          placeholder="监听地址"
          style={{ marginRight: '8px', width: '240px' }}
        />
        <button style={{ marginRight: '8px' }} onClick={startListening}>开始</button>
        <button style={{ marginRight: '8px' }} onClick={stopListening}>停止</button>
      </div>

      <TracklineVisual
        rows={rows}
        columns={columns}
        cellSize={50}
        gap={1}
        lines={lines}
        onLineDrawn={handleLineDrawn}
        updateLine={updateLine}
        platformsState={platforms}
        updatePlatformsState={setPlatforms}
        editMode={editMode}
        tracklights={tracklights}
        updateTracklight={updateTracklight}
        deleteTracklight={deleteTracklight}
        deletePlatform={deletePlatform}
        deleteLine={deleteLine}
        deleteMode={deleteMode}
        drawPlatformMode={drawPlatformMode}
        setDrawPlatformMode={(active) => setMode(active ? "drawPlatform" : "none")}
        editTracklightMode={editTracklightMode}
        setTracklights={setTracklights}
        setLines={setLines}
        svgRef={svgRef}
        trains={trains}
        signals={signals}
      />
    </div>
  );
}

export default VisualTrackline;